package com.iteaj.iot.client.udp;

import com.iteaj.iot.client.TcpRequestProtocol;
import com.iteaj.iot.client.TcpSocketClient;
import com.iteaj.network.ProtocolException;
import com.iteaj.network.message.UnParseBodyMessage;
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.socket.DatagramPacket;
import io.netty.channel.socket.nio.NioDatagramChannel;

import java.io.IOException;
import java.net.InetSocketAddress;

public abstract class UdpSocketClient extends TcpSocketClient {

    public UdpSocketClient(UdpClientComponent clientComponent) {
        super(clientComponent, null);
    }

    @Override
    protected void doInitOptions(Bootstrap bootstrap) {
        bootstrap.option(ChannelOption.SO_BROADCAST, true);
    }

    @Override
    protected Class<? extends Channel> channel() {
        return NioDatagramChannel.class;
    }

    @Override
    public void doConnect() {
        getBootstrap().bind(0).addListener(future -> {
            connectLogger((ChannelFuture) future);
        });
    }

    @Override
    public void doConnect(long timeout) throws ProtocolException {
        /*doing nothing*/
    }

    @Override
    protected abstract DatagramPacketToMessageDecoder getClientProtocolDecoder();

    /**
     * 写出的报文必须是 UdpRequestProtocol 协议类型
     * @param clientRequestProtocol
     * @return
     */
    @Override
    public ChannelFuture writeAndFlush(TcpRequestProtocol clientRequestProtocol) {
        // 写入Udp报文 DatagramPacket
        if(clientRequestProtocol instanceof UdpRequestProtocol) {
            try {
                UnParseBodyMessage clientMessage = clientRequestProtocol.requestMessage().build();

                final ByteBuf byteBuf = Unpooled.wrappedBuffer(clientMessage.getMessage());
                final DatagramPacket packet = new DatagramPacket(byteBuf, new InetSocketAddress(getHost(), getPort()));
                ((UdpRequestProtocol) clientRequestProtocol).setPacket(packet);
            } catch (IOException e) {
                e.printStackTrace();
            }
        } else {
            throw new ProtocolException("Udp客户端只支持写出协议类型["+UdpRequestProtocol.class.getSimpleName()+"]");
        }

        return super.writeAndFlush(clientRequestProtocol);
    }
}
